package com.xmy.cultivate.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xmy.cultivate.characteristic.ALiYunSmsCharacteristic;
import com.xmy.cultivate.entity.Admin;
import com.xmy.cultivate.entity.ResetPasswordAndRetrieveAccount;
import com.xmy.cultivate.entity.Staff;
import com.xmy.cultivate.service.IAdminService;
import com.xmy.cultivate.service.IResetPasswordAndRetrieveAccountService;
import com.xmy.cultivate.service.IStaffService;
import com.xmy.cultivate.util.Code;
import com.xmy.cultivate.util.CommonUtil;
import com.xmy.cultivate.util.Result;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;
import java.util.Random;

@RestController
@RequestMapping("/api/resetPasswordAndRetrieveAccount")
public class ResetPasswordAndRetrieveAccountController {
    @Autowired
    IStaffService iStaffService;
    @Autowired
    IAdminService iAdminService;

    @Resource
    ALiYunSmsCharacteristic aliyunSmsCharacteristic;

    @Autowired
    IResetPasswordAndRetrieveAccountService iResetPasswordAndRetrieveAccountService;

    @Value("${aliyun.sms.signName}")
    String signName;
    @Value("${aliyun.sms.templateCode}")
    String templateCode;
    @Value("${aliyun.sms.signNameString}")
    String signNameString;
    @Value("${aliyun.sms.templateCodeString}")
    String templateCodeString;
    @Value("${aliyun.AccessKeyID}")
    String accessKeyID;
    @Value("${aliyun.AccessKeySecret}")
    String accessKeySecret;
    @Value("${aliyun.sms.registerSignName}")
    String registerSignName;
    @Value("${aliyun.sms.registerTemplateCode}")
    String registerTemplateCode;

    @ApiOperation("查询账号")
    @GetMapping("getAccount")
    public Result getAccount(@RequestParam("account") String account){
        Admin adminServiceOne = iAdminService.getOne(new QueryWrapper<Admin>().eq("account", account).eq("deleted", 0).last("LIMIT 1"));
        int i = 1;
        if (adminServiceOne == null){
            i = 0;
        }
        return new Result(Code.OK,i);
    }

    @ApiOperation("获取验证码")
    @GetMapping("getMobileAreaCode")
    public Result getMobileAreaCode(@RequestParam("phone") String phone, @RequestParam(value = "account", required = false) String account){
        Staff staffServiceOne = iStaffService.getOne(new QueryWrapper<Staff>().eq("phone", phone).eq("deleted", 0).last("LIMIT 1"));
        if (staffServiceOne == null) {
            return new Result(Code.ERROR,0,"手机号码不存在，请先注册！");
        }
        if (account != null && !account.isEmpty()) {
            long countAdmin = iAdminService.count(new QueryWrapper<Admin>().eq("account", account).eq("id", staffServiceOne.getAdminId()).eq("deleted", 0));
            if (countAdmin == 0L) {
                return new Result(Code.ERROR, 0, "手机号码绑定的账号不一至，请找回账号！");
            }
        }
        long timestamp = System.currentTimeMillis() / 1000;
        String code = generatePhoneVerificationCode();
        ResetPasswordAndRetrieveAccount retrieveAccount = new ResetPasswordAndRetrieveAccount();
        retrieveAccount.setState(0);//0未使用；1已使用
        retrieveAccount.setPhone(phone);
        retrieveAccount.setTimestamp((int) timestamp);
        retrieveAccount.setVerifyCode(code);
        retrieveAccount.setType(2);//0重置密码；1找回账号；2测试；3注册
        iResetPasswordAndRetrieveAccountService.save(retrieveAccount);
        return new Result(Code.OK, code, "您的验证码为：" + code + "，请在5分钟内输入");
    }

    @ApiOperation("判断验证码")
    @GetMapping("JudgeMobileAreaCode")
    public Result JudgeMobileAreaCode(@RequestParam("phone") String phone, @RequestParam("code") String code, @RequestParam(value = "account", required = false) String account){
        int type = 2;
        ResetPasswordAndRetrieveAccount retrieveAccountServiceOne = iResetPasswordAndRetrieveAccountService.getOne(new QueryWrapper<ResetPasswordAndRetrieveAccount>().eq("phone", phone).eq("type", type).orderByDesc("timestamp").last("LIMIT 1"));
        return getJudge(code, retrieveAccountServiceOne,type, account);
    }

    @ApiOperation("获取重置密码验证码")
    @GetMapping("getResetPasswordCode")
    public Result getResetPasswordCode(@RequestParam("phone") String phone, @RequestParam(value = "account") String account){
        Staff staffServiceOne = iStaffService.getOne(new QueryWrapper<Staff>().eq("phone", phone).eq("deleted", 0).last("LIMIT 1"));
        if (staffServiceOne == null) {
            return new Result(Code.ERROR,0,"手机号码不存在，请先注册！");
        }
        long countAdmin = iAdminService.count(new QueryWrapper<Admin>().eq("account", account).eq("id", staffServiceOne.getAdminId()).eq("deleted", 0));
        if (countAdmin == 0L) {
            return new Result(Code.ERROR,0,"手机号码绑定的账号不一至，请找回账号！");
        }
        long timestamp = System.currentTimeMillis() / 1000;
        String code = generatePhoneVerificationCode();
        ResetPasswordAndRetrieveAccount retrieveAccount = new ResetPasswordAndRetrieveAccount();
        retrieveAccount.setState(0);//0未使用；1已使用
        retrieveAccount.setPhone(phone);
        retrieveAccount.setTimestamp((int) timestamp);
        retrieveAccount.setVerifyCode(code);
        retrieveAccount.setType(0);//0重置密码；1找回账号；2测试；3注册
        boolean save = iResetPasswordAndRetrieveAccountService.save(retrieveAccount);
        if (save) {
            boolean b = goToSms(phone, code);
            if (b) {
                return new Result(Code.OK, 1, "重置密码验验证码已发送成功！请在5分钟内输入！");
            }
        }
        return new Result(Code.ERROR, 0, "重置密码验验证码发送失败！请重新获取！");
    }
    @ApiOperation("判断重置密码验证码")
    @GetMapping("JudgeResetPasswordCode")
    public Result JudgeResetPasswordCode(@RequestParam("phone") String phone, @RequestParam("code") String code, @RequestParam(value = "account") String account){
        int type = 0;
        ResetPasswordAndRetrieveAccount retrieveAccountServiceOne = iResetPasswordAndRetrieveAccountService.getOne(new QueryWrapper<ResetPasswordAndRetrieveAccount>().eq("phone", phone).eq("type", type).orderByDesc("timestamp").last("LIMIT 1"));
        return getJudge(code, retrieveAccountServiceOne,type, account);
    }
    @ApiOperation("获取找回账号验证码")
    @GetMapping("getRetrieveAccountCode")
    public Result getRetrieveAccountCode(@RequestParam("phone") String phone){
        Staff staffServiceOne = iStaffService.getOne(new QueryWrapper<Staff>().eq("phone", phone).eq("deleted", 0).last("LIMIT 1"));
        if (staffServiceOne == null) {
            return new Result(Code.ERROR,0,"手机号码不存在，请先注册！");
        }
        long timestamp = System.currentTimeMillis() / 1000;
        String code = generatePhoneVerificationCode();
        ResetPasswordAndRetrieveAccount retrieveAccount = new ResetPasswordAndRetrieveAccount();
        retrieveAccount.setState(0);//0未使用；1已使用
        retrieveAccount.setPhone(phone);
        retrieveAccount.setTimestamp((int) timestamp);
        retrieveAccount.setVerifyCode(code);
        retrieveAccount.setType(1);//0重置密码；1找回账号；2测试；3注册
        boolean save = iResetPasswordAndRetrieveAccountService.save(retrieveAccount);
        if (save) {
            boolean b = goToSms(phone, code);
            if (b) {
                return new Result(Code.OK, 1, "找回账号验证码已发送成功！请在5分钟内输入！");
            }
        }
        return new Result(Code.ERROR, 0, "找回账号验证码发送失败！请重新获取！");
    }
    @ApiOperation("判断找回账号验证码")
    @GetMapping("JudgeRetrieveAccountCode")
    public Result JudgeRetrieveAccountCode(@RequestParam("phone") String phone, @RequestParam("code") String code){
        int type = 1;
        ResetPasswordAndRetrieveAccount retrieveAccountServiceOne = iResetPasswordAndRetrieveAccountService.getOne(new QueryWrapper<ResetPasswordAndRetrieveAccount>().eq("phone", phone).eq("type", type).orderByDesc("timestamp").last("LIMIT 1"));
        return getJudge(code, retrieveAccountServiceOne,type, null);
    }

    @ApiOperation("获取注册验证码")
    @GetMapping("getRegisterCode")
    public Result getRegisterCode(@RequestParam("phone") String phone){
        Staff staffServiceOne = iStaffService.getOne(new QueryWrapper<Staff>().eq("phone", phone).eq("deleted", 0).last("LIMIT 1"));
        if (staffServiceOne != null) {
            return new Result(Code.ERROR,0,"手机号码已存在，请用其他手机号码，或到登录页面登录！");
        }
        long timestamp = System.currentTimeMillis() / 1000;
        String code = generatePhoneVerificationCode();
        ResetPasswordAndRetrieveAccount retrieveAccount = new ResetPasswordAndRetrieveAccount();
        retrieveAccount.setState(0);//0未使用；1已使用
        retrieveAccount.setPhone(phone);
        retrieveAccount.setTimestamp((int) timestamp);
        retrieveAccount.setVerifyCode(code);
        retrieveAccount.setType(3);//0重置密码；1找回账号；2测试；3注册
        boolean save = iResetPasswordAndRetrieveAccountService.save(retrieveAccount);
        if (save) {
            boolean b = goToSmsRegister(phone, code);
            if (b) {
                return new Result(Code.OK, 1, "注册验验证码已发送成功！请在5分钟内输入！");
            }
        }
        return new Result(Code.ERROR, 0, "注册验验证码发送失败！请重新获取！");
    }
    @ApiOperation("判断注册验证码")
    @GetMapping("JudgeRegisterCode")
    public Result JudgeRegisterCode(@RequestParam("phone") String phone, @RequestParam("code") String code){
        int type = 3;
        ResetPasswordAndRetrieveAccount retrieveAccountServiceOne = iResetPasswordAndRetrieveAccountService.getOne(new QueryWrapper<ResetPasswordAndRetrieveAccount>().eq("phone", phone).eq("type", type).orderByDesc("timestamp").last("LIMIT 1"));
        return getJudge(code, retrieveAccountServiceOne,type, null);
    }

    @NotNull
    private Result getJudge(@RequestParam("code") String code, ResetPasswordAndRetrieveAccount retrieveAccountServiceOne, int type, String account) {
        if (retrieveAccountServiceOne == null) {
            return new Result(Code.ERROR,0,"验证码错误，请重新获取！");
        }
        if ((type == 2 || type == 0) && account != null && !account.isEmpty()) {
            Admin adminServiceOne = iAdminService.getOne(new QueryWrapper<Admin>().eq("account", account).eq("deleted", 0).last("LIMIT 1"));
            long countStaff = iStaffService.count(new QueryWrapper<Staff>().eq("phone", retrieveAccountServiceOne.getPhone()).eq("admin_id", adminServiceOne.getId()).eq("deleted", 0));
            if (countStaff == 0L) {
                return new Result(Code.ERROR,0,"手机号码绑定的账号不一至，请找回账号！");
            }
        }
        long timestamp = System.currentTimeMillis() / 1000;
        int time = (int) timestamp;
        int getTimestamp = retrieveAccountServiceOne.getTimestamp();
        int isIfTime = time - getTimestamp;
        if (isIfTime > 300) {
            return new Result(Code.ERROR,0,"验证码超时！请重新获取！");
        }
        if (retrieveAccountServiceOne.getState() == 1) {
            return new Result(Code.ERROR,0,"验证码不正确！请重新获取。");
        }
        if (retrieveAccountServiceOne.getType() != type) {
            return new Result(Code.ERROR,0,"验证码不正确！请重新获取！");
        }
        if (!Objects.equals(code, retrieveAccountServiceOne.getVerifyCode())) {
            return new Result(Code.ERROR,0,"验证码不正确！");
        }
        retrieveAccountServiceOne.setState(1);
        iResetPasswordAndRetrieveAccountService.updateById(retrieveAccountServiceOne);
        if (type == 1 || type == 2) {
            Staff staffServiceOne = iStaffService.getOne(new QueryWrapper<Staff>().eq("phone", retrieveAccountServiceOne.getPhone()).eq("deleted", 0).last("LIMIT 1"));
            Admin adminServiceOne = iAdminService.getOne(new QueryWrapper<Admin>().eq("id", staffServiceOne.getAdminId()).eq("deleted", 0).last("LIMIT 1"));
            if (adminServiceOne != null) {
//                if (type == 1) {//这里不要了，只要注册的
//                    boolean b = goToSmsString(retrieveAccountServiceOne.getPhone(), adminServiceOne.getAccount());
//                    if (!b) {
//                        return new Result(Code.OK, adminServiceOne.getAccount(), adminServiceOne.getAccount() + "账号发送到手机失败！模板不支持字符串！");
//                    }
//                }
                return new Result(Code.OK, adminServiceOne.getAccount(), "验证码正确，您的账号：" + adminServiceOne.getAccount());
            }
        }
        return new Result(Code.OK,1,"验证码正确");
    }

    @ApiOperation("生成一个六位数的随机数")
    private static String generatePhoneVerificationCode() {
        Random random = new Random();
        int verificationCode = random.nextInt(999999) + 100000; // 生成一个六位数的随机数
        return String.valueOf(verificationCode);
    }

    @ApiOperation("发送4-6位随机纯数字")
    private boolean goToSms(String phone, String code) {
        return aliyunSmsCharacteristic.goToSms(accessKeyID,accessKeySecret,this.signName,this.templateCode,phone,code);
    }

    @ApiOperation("发送4-6位随机纯数字，注册码")
    private boolean goToSmsRegister(String phone, String code) {
        return aliyunSmsCharacteristic.goToSms(accessKeyID,accessKeySecret,this.registerSignName,this.registerTemplateCode,phone,code);
    }

    @ApiOperation("发送字符串账号")
    private boolean goToSmsString(String phone, String code) {
        return aliyunSmsCharacteristic.goToSms(accessKeyID,accessKeySecret,this.signNameString,this.templateCodeString,phone,code);
    }

    @ApiOperation("输入新密码")
    @PostMapping("newResetPasswordCode")
    public Result newResetPasswordCode(@RequestBody Map<String, Object> reMap){
        String phone = (String) reMap.get("phone");
        String password = (String) reMap.get("password");
        String confirmPassword = (String) reMap.get("confirmPassword");
        String account = (String) reMap.get("account");
        if (!Objects.equals(password, confirmPassword)) {
            return new Result(Code.ERROR,0,"两次密码不一至！");
        }
        Staff staffServiceOne = iStaffService.getOne(new QueryWrapper<Staff>().eq("phone", phone).eq("deleted", 0).last("LIMIT 1"));
        Admin adminServiceOne = iAdminService.getOne(new QueryWrapper<Admin>().eq("id", staffServiceOne.getAdminId()).eq("account", account).eq("deleted", 0).last("LIMIT 1"));
        if (adminServiceOne == null) {
            return new Result(Code.ERROR,0,"手机号码绑定的账号不一至，请找回账号！");
        }
        if (StringUtils.isNotBlank(password)) {
            boolean rs = CommonUtil.isPasswordAvailable("",password);
            if (!rs){
                return new Result(Code.ERROR,0,"密码不能包含4位以上连续数字或字符");
            }

            String pwd = new Md5Hash(password, account, 3).toString();
            adminServiceOne.setPwd(pwd);
            iAdminService.updateById(adminServiceOne);
        }
        return new Result(Code.OK,1,"密码重置成功！");
    }

}
